#include <iostream>
#include "sqlite_database.h"

void print() { std::cout << std::endl; }
template<typename T, typename... Args>
void print(T&& first, Args&&... args) {
    std::cout << std::forward<T>(first) << ' ';
    print(std::forward<Args>(args)...);
}
#define Print(...) print(__func__, ##__VA_ARGS__)
#define UNUSED(x) (void)x

class User : public SqliteRowData {
public:
    InitializeSqliteRowData(User, 4, uid, name, email, age);

    User(const std::string& uid, const std::string& name, const std::string& email, int age)
        :SqliteRowData("User", 4), uid(uid), name(name), email(email), age(age) { SqliteRowData::__initializeConstructor(); }

    std::string uid;
    std::string name;
    std::string email;
    int age;
};

// 用户数据访问对象
class UserDAO {
private:
    SqliteDatabase& database;

public:
    explicit UserDAO(SqliteDatabase& db) : database(db) {
        create_table();
    }

    void create_table() {
        const std::string sql = R"(
            CREATE TABLE IF NOT EXISTS User (
                uid TEXT PRIMARY KEY,
                name TEXT NOT NULL,
                email TEXT UNIQUE NOT NULL,
                age INTEGER DEFAULT 0
            )
        )";
        print("创建表:", database.execute(sql));
    }

    // 创建用户
    bool insert_user(User& user) {
        const std::string& sql = user.sqlInsert();
        std::cout << sql << std::endl;
        return database.execute(sql);
    }

    // 查询所有用户
    std::vector<User> get_all_users() {
        User temp;
        temp.addOrderBy();
        const std::string sql = temp.sqlSelect();
        std::cout << sql << std::endl;
        std::vector<User> users;
        database.select(sql, [&users, this](sqlite3_stmt* stmt){
            User user;
            database.getRowData(stmt, user);
            users.push_back(user);
        });
        return users;
    }

    // 根据ID查询用户
    bool get_user_by_uid(User& user, const std::string& uid) {
        user.uid = uid;
        const std::string sql = user.sqlSelect(0);
        std::cout << sql << std::endl;
        return database.selectSelf(sql, user);
    }

    // 根据邮箱查询用户
    bool get_user_by_email(User& user, const std::string& email) {
        user.email = email;
        const std::string sql = user.sqlSelect(2);
        std::cout << sql << std::endl;
        return database.selectSelf(sql, user);
    }

    // 更新用户
    bool update_user(User& user) {
        const std::string sql = user.sqlUpdate({1, 2, 3}, 0);
        std::cout << sql << std::endl;
        return database.execute(sql);
    }

    // 删除用户
    bool delete_user(const std::string& uid) {
        User user;
        user.uid = uid;
        const std::string sql = user.sqlDelete(0);
        std::cout << sql << std::endl;
        return database.execute(sql);
    }

    // 获取用户总数
    bool get_user_count(int& count) {
        const std::string sql = "SELECT COUNT(*) FROM User";
        return database.selectOne(sql, count);
    }
};

// 打印用户信息
void print_user(const User& user) {
    std::cout << "UID: " << user.uid
              << ", 姓名: " << user.name
              << ", 邮箱: " << user.email
              << ", 年龄: " << user.age << std::endl;
}

// 打印所有用户
void print_all_users(const std::vector<User>& users) {
    std::cout << "用户列表 (" << users.size() << " 个用户):" << std::endl;
    for (const auto& user : users) {
        print_user(user);
    }
    std::cout << std::endl;
}

int main() {
    // 创建数据库连接
    SqliteDatabase db("/tmp/itopsmart_example.db");

    // 创建用户 DAO
    UserDAO user_dao(db);

    std::cout << "=== SQLite C++ CRUD 操作示例 ===" << std::endl;

    // 1. 插入用户
    std::cout << "1. 插入用户:" << std::endl;
    User user1("001", "张三", "zhangsan@example.com", 25);
    User user2("002", "李四", "lisi@example.com", 30);
    User user3("003", "王五", "wangwu@example.com", 28);

    bool r1 = user_dao.insert_user(user1);
    bool r2 = user_dao.insert_user(user2);
    bool r3 = user_dao.insert_user(user3);

    std::cout << "插入用户结果: " << r1 << ", " << r2 << ", " << r3 << std::endl;

    // 2. 查询所有用户
    std::cout << "\n2. 查询所有用户:" << std::endl;
    auto all_users = user_dao.get_all_users();
    print_all_users(all_users);

    // 3. 根据ID查询用户
    std::cout << "3. 根据ID查询用户:" << std::endl;
    User uid_user;
    bool found_user = user_dao.get_user_by_uid(uid_user, "001");
    if(found_user){
        std::cout << "找到用户: ";
        print_user(uid_user);
    }else{
        std::cout << "001 未找到用户: ";
    }

    // 4. 根据邮箱查询用户
    std::cout << "\n4. 根据邮箱查询用户:" << std::endl;
    User email_user;
    found_user = user_dao.get_user_by_email(email_user, "lisi@example.com");
    if(found_user){
        std::cout << "找到用户: ";
        print_user(email_user);
    }else{
        std::cout << "lisi@example.com 未找到用户: ";
    }

    // 5. 更新用户
    std::cout << "\n5. 更新用户:" << std::endl;
    user1.name = "张三丰";
    user1.age = 35;

    bool updated = user_dao.update_user(user1);
    std::cout << "更新用户" << (updated ? "成功" : "失败") << std::endl;

    // 6. 获取用户总数
    int count = 0;
    std::cout << "\n6. 结果:" << user_dao.get_user_count(count) << ",用户总数: " << count << std::endl;

    // 7. 删除用户
    std::cout << "\n7. 删除用户:" << std::endl
    bool deleted = user_dao.delete_user("001");
    std::cout << "删除用户" << (deleted ? "成功" : "失败") << std::endl;

    std::cout << "\n7. 结果:" << user_dao.get_user_count(count) << ",用户总数: " << count << std::endl;

    return 0;
}
